import 'package:flutter/material.dart';

import 'widgets/main/app_splash.dart';
import 'util/_base_export.dart';
import 'util/_initwork.dart';

import 'package:logging/logging.dart';
import 'package:catcher/catcher.dart';
import 'package:catcher/model/report.dart';
import 'package:catcher/model/report_handler.dart';
import 'package:catcher/model/platform_type.dart';

import 'package:pushy_flutter/pushy_flutter.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await Firebase.initializeApp();
  await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true);

  CatcherOptions debugOptions = CatcherOptions(DialogReportMode(), [CrashlyticsHandler()]);

  /// Release configuration. Same as above, but once user accepts dialog, user will be prompted to send email with crash to support.
  CatcherOptions releaseOptions = CatcherOptions(SilentReportMode(), [
    // EmailManualHandler(["bug@rotating.ca"]),
    CrashlyticsHandler()
  ]);

  /// STEP 2. Pass your root widget (MyApp) along with Catcher configuration:
  Catcher(rootWidget:AppSplashView(), debugConfig: debugOptions, releaseConfig: releaseOptions);
}

class CrashlyticsHandler extends ReportHandler {
  final Logger _logger = Logger("CrashlyticsHandler");
  final bool enableDeviceParameters;
  final bool enableApplicationParameters;
  final bool enableCustomParameters;
  final bool printLogs;
  CrashlyticsHandler(
      {this.enableDeviceParameters = true,
      this.enableApplicationParameters = true,
      this.enableCustomParameters = true,
      this.printLogs = true}
      );
  @override
  List<PlatformType> getSupportedPlatforms() {
    return [PlatformType.android, PlatformType.iOS];
  }

  @override
  Future<bool> handle(Report report, BuildContext? context) async {
    try {
      _printLog("Sending crashlytics report");
      // var crashlytics = Crashlytics.instance;
      // crashlytics.enableInDevMode = true;
      FirebaseCrashlytics.instance.log(_getLogMessage(report));
      if (report.errorDetails != null) {
        await FirebaseCrashlytics.instance.recordFlutterError(report.errorDetails!);
      } else {
        await FirebaseCrashlytics.instance.recordError(report.error, report.stackTrace);
      }
      _printLog("Crashlytics report sent");
      return true;
    } catch (exception) {
      _printLog("Failed to send crashlytics report: " + exception.toString());
      return false;
    }
  }

  String _getLogMessage(Report report) {
    StringBuffer buffer = StringBuffer("");
    if (enableDeviceParameters) {
      buffer.write("||| Device parameters ||| ");
      for (var entry in report.deviceParameters.entries) {
        buffer.write("${entry.key}: ${entry.value} ");
      }
    }
    if (enableApplicationParameters) {
      buffer.write("||| Application parameters ||| ");
      for (var entry in report.applicationParameters.entries) {
        buffer.write("${entry.key}: ${entry.value} ");
      }
    }
    if (enableCustomParameters) {
      buffer.write("||| Custom parameters ||| ");
      for (var entry in report.customParameters.entries) {
        buffer.write("${entry.key}: ${entry.value} ");
      }
    }
    return buffer.toString();
  }

  void _printLog(String log) {
    if (printLogs) {
      _logger.info(log);
    }
  }
}
